package service

import (
	"github.com/go-xorm/xorm"

	"im/dao"
	"im/errcode"
	"im/model"
	"im/responses"
	"im/service/orm"
)

type GroupUsersService interface {
	// GetAll() []model.Groups
	// GetByID(id int64) (model.Groups, bool)
	DeleteByID(appsId uint, groupId int64, userId int64) (int64, error)
	Create(data *model.GroupsUsers) (error)
	GetListByUser(appsId uint, userId int64) (*[]int64, error)
	DeleteByGroupId(appsId uint, groupId int64) (int64, error)
	IsUserInChatGroup(userId int64, groupId int64) bool
	GetListByGroupId(groupId int64) (responses.GetGroupsUsers, error)
	Modify(userId int64, data model.GroupsUsersModifiable) error
}

var rolesMap = map[byte]string{
	model.GROUP_USER_ROLE_IS_OWNER:  "群主",
	model.GROUP_USER_ROLE_IS_ADMIN:  "管理员",
	model.GROUP_USER_ROLE_IS_MEMBER: "成员",
}

func NewGroupUsersService() GroupUsersService {
	return &groupsUsersService{db: orm.GetDB()}
}

type groupsUsersService struct {
	db *xorm.Engine
}

func (c *groupsUsersService) IsUserInChatGroup(userId int64, groupId int64) bool {
	exist, err := c.db.Where("group_id=?", groupId).Where("user_id=?", userId).Where("status=?", 1).Exist(&model.GroupsUsers{})
	if err != nil {
		_ = errcode.NewError(errcode.DaoFailed, err)
		return false
	}
	return exist
}

func (c *groupsUsersService) GetListByUser(appsId uint, userId int64) (r *[]int64, e error) {
	list := &[]model.GroupsUsers{}
	err := c.db.Cols("group_id").Where("apps_id=?", appsId).Where("user_id=?", userId).Where("status=?", 1).Find(list)
	if err != nil {
		return nil, err
	}
	r = new([]int64)
	for _, v := range *list {
		*r = append(*r, v.GroupId)
	}
	return r, nil
}

func (c *groupsUsersService) GetListByGroupId(groupId int64) (responses.GetGroupsUsers, error) {
	groupUsers, err := dao.NewGroupsUsersDao().GetListByGroupId(groupId)
	var resp = responses.GetGroupsUsers{
		Managers: []responses.GroupUsersFormatted{},
		Members:  []responses.GroupUsersFormatted{},
	}
	if err != nil {
		return resp, err
	}
	for _, u := range groupUsers {
		switch u.Role {
		case model.GROUP_USER_ROLE_IS_OWNER:
			fallthrough
		case model.GROUP_USER_ROLE_IS_ADMIN:
			resp.Managers = append(resp.Managers, responses.GroupUsersFormatted{
				GroupsUsers: u,
				RoleName:    rolesMap[u.Role],
			})
		case model.GROUP_USER_ROLE_IS_MEMBER:
			resp.Members = append(resp.Members, responses.GroupUsersFormatted{
				GroupsUsers: u,
				RoleName:    rolesMap[u.Role],
			})
		}
	}
	return resp, nil

}

func (c *groupsUsersService) DeleteByID(appsId uint, groupId int64, userId int64) (int64, error) {
	data := &model.GroupsUsers{Status: -1}
	return dao.NewGroupsUsersDao().Update(appsId, groupId, userId, data, "status")
}

func (c *groupsUsersService) DeleteByGroupId(appsId uint, groupId int64) (int64, error) {
	data := &model.GroupsUsers{Status: -1}
	return c.db.Where("apps_id=?", appsId).Where("group_id=?", groupId).Where("status=1").Update(data)
}

func (c *groupsUsersService) Create(data *model.GroupsUsers) error {
	exist,err := c.db.Where("apps_id=?", data.AppsId).Where("group_id=?", data.GroupId).Where("user_id=?", data.UserId).Exist(&model.GroupsUsers{})
	if err!=nil{
		return errcode.NewError(errcode.DaoFailed,err)
	}
	if exist{
		_,err =c.db.Cols("role", "status", "joined").Where("apps_id=?", data.AppsId).Where("group_id=?", data.GroupId).Where("user_id=?", data.UserId).
			Where("role!=?", 0).Update(data)
	}else {
		_, err =c.db.InsertOne(data)
	}
	return err
}

func (c *groupsUsersService) Modify(userId int64, data model.GroupsUsersModifiable) error {
	return dao.NewGroupsUsersDao().Modify(userId, data)
}
